﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using GenericValidation;
using Microsoft.Practices.Unity;
using System.Reflection;
using GenericValidation.Resources;
using System.Resources;

namespace GenericValidation.Sample
{
    /// <summary>
    /// Validation Factory that uses Unity container from Microsoft, Patterns & Practices
    /// </summary>
    public class UnityValidationFactory : IValidationFactory
    {
        public IUnityContainer Container { get; set; }

        public UnityValidationFactory(IUnityContainer container, Assembly assembly)
        {
            this.Container = container;
            this.LoadFromAssembly(assembly);
        }

        public void LoadFromAssembly(Assembly assembly)
        {
            var types = assembly.GetTypes();
            var validations = (from p in types
                               where p.GetInterface(typeof(IValidation).Name) != null && p.BaseType.IsGenericType
                               select new
                               {
                                   ItemType = p.BaseType.GetGenericArguments()[0],
                                   ValidationType = p
                               }).ToList();

            validations.ForEach(p => {
                var itemValidationType = typeof(Validation<>).MakeGenericType(p.ItemType);
                this.Container.RegisterType(itemValidationType, p.ValidationType);
            });
        }

        #region IValidationFactory Members

        public IValidation Resolve<T>()
        {
            return this.Resolve(typeof(T));
        }

        public IValidation Resolve(Type itemType)
        {
            var validationType = typeof(Validation<>).MakeGenericType(itemType);
            var theResult = (IValidation) this.Container.Resolve(validationType);
            return theResult;
        }

        public ResourceManager GetResourceManager<T>()
        {
            return Messages.ResourceManager;
        }

        #endregion
    }
}
